package com.sum.slike;

import com.sum.slike.utils.PixelUtil;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.global.resource.Resource;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;
import ohos.utils.LruBuffer;

/**
 * @author: zhu_zhonglin
 * @time: 2021/4/26
 */
public class BitmapProvider {
    /**
     * 默认Provider
     */
    static class Default implements Provider {

        private LruBuffer<Integer, PixelMap> bitmapLruCache;
        private int NUMBER_PREFIX = 0x70000000;
        private int LEVEL_PREFIX = 0x80000000;
        private int[] drawableArray;
        private int[] numberDrawableArray;
        private int[] levelDrawableArray;
        private String[] levelStringArray;
        private Context context;
        private float textSize;

        Default(Context context, int cacheSize, int[] drawableArray, int[] numberDrawableArray,
                int[] levelDrawableArray, String[] levelStringArray, float textSize) {
            bitmapLruCache = new LruBuffer<>(cacheSize);
            this.drawableArray = drawableArray;
            this.numberDrawableArray = numberDrawableArray;
            this.levelDrawableArray = levelDrawableArray;
            this.levelStringArray = levelStringArray;
            this.context = context;
            this.textSize = textSize;
        }

        @Override
        public PixelMap getNumberBitmap(int number) {
            PixelMap bitmap;
            if (numberDrawableArray != null && numberDrawableArray.length > 0) {
                int index = number % numberDrawableArray.length;
                bitmap = bitmapLruCache.get(NUMBER_PREFIX | numberDrawableArray[index]);
                if (bitmap == null) {
                    bitmap = convertResToPixelMap(numberDrawableArray[index], false);
                    bitmapLruCache.put(NUMBER_PREFIX | numberDrawableArray[index], bitmap);
                }
            } else {
                bitmap = bitmapLruCache.get(NUMBER_PREFIX | number);
                if (bitmap == null) {
                    bitmap = createBitmapByText(textSize, String.valueOf(number));
                    bitmapLruCache.put(NUMBER_PREFIX | number, bitmap);
                }
            }
            return bitmap;
        }


        private PixelMap convertResToPixelMap(int drawableRes, boolean adjustSize) {
            PixelMap bitmap = null;
            try {
                Resource resource = context.getResourceManager().getResource(drawableRes);
                ImageSource imageSource = ImageSource.create(resource, null);
                if (adjustSize) {
                    ImageSource.DecodingOptions options = new ImageSource.DecodingOptions();
                    options.desiredSize = new Size(100, 100);
                    bitmap = imageSource.createPixelmap(options);
                } else {
                    bitmap = imageSource.createPixelmap(null);
                }
                return bitmap;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bitmap;
        }


        @Override
        public PixelMap getLevelBitmap(int level) {
            PixelMap bitmap;
            if (levelDrawableArray != null && levelDrawableArray.length > 0) {
                int index = Math.min(level, levelDrawableArray.length);
                bitmap = bitmapLruCache.get(LEVEL_PREFIX | levelDrawableArray[index]);
                if (bitmap == null) {
                    bitmap = convertResToPixelMap(levelDrawableArray[index], false);
                    bitmapLruCache.put(LEVEL_PREFIX | levelDrawableArray[index], bitmap);
                }
            } else {
                bitmap = bitmapLruCache.get(LEVEL_PREFIX | level);
                if (bitmap == null) {
                    int index = Math.min(level, levelStringArray.length);
                    bitmap = createBitmapByText(textSize, levelStringArray[index]);
                    bitmapLruCache.put(LEVEL_PREFIX | level, bitmap);
                }
            }
            return bitmap;
        }

        @Override
        public PixelMap getRandomBitmap() {
            int index = (int) (Math.random() * drawableArray.length);
            PixelMap bitmap = bitmapLruCache.get(drawableArray[index]);
            if (bitmap == null) {
                bitmap = convertResToPixelMap(drawableArray[index], true);
                bitmapLruCache.put(drawableArray[index], bitmap);
            }
            return bitmap;
        }

        /**
         * 创建文字相关的图片
         * @param textSize textSize
         * @param text text
         * @return PixelMap
         */
        public PixelMap createBitmapByText(float textSize, String text) {
            Paint textPaint = new Paint();
            textPaint.setColor(Color.BLACK);
            textPaint.setTextSize((int) textSize);
            PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
            options.pixelFormat = PixelFormat.ARGB_8888;


            int width = (int) textPaint.measureText(String.valueOf(text));
            int height = (int) textSize;
            PixelMap.InitializationOptions opts = new PixelMap.InitializationOptions();
            opts.size = new Size(width, height);
            opts.pixelFormat = PixelFormat.ARGB_8888;
            PixelMap bitmap = PixelMap.create(opts);

//            PixelMap bitmap = PixelMap.create((int)textPaint.measureText(String.valueOf(text)),
//                    (int)textSize, options);


            Canvas canvas = new Canvas();
            canvas.setTexture(new Texture(bitmap));

//            canvas.setMatrix();
//            canvas.drawRect(rect, textPaint);
            canvas.drawColor(Color.TRANSPARENT.getValue(), Canvas.PorterDuffMode.SRC_OVER);
            canvas.drawText(textPaint, String.valueOf(text), 0, textSize);
//            canvas.draw
            return bitmap;
        }
    }

    /**
     * 建造者模式
     */
    public static class Builder {
        Context context;
        private int cacheSize;
        int[] drawableArray;
        int[] numberDrawableArray;
        int[] levelDrawableArray;
        String[] levelStringArray;
        private float textSize;

        public Builder(Context context) {
            this.context = context;
        }

        /**
         * 设置缓存大小
         * @param cacheSize cacheSize
         * @return Builder
         */
        public Builder setCacheSize(int cacheSize) {
            this.cacheSize = cacheSize;
            return this;
        }

        /**
         * 设置图片资源列表
         * @param drawableArray drawableArray
         * @return Builder
         */
        public Builder setDrawableArray(int[] drawableArray) {
            this.drawableArray = drawableArray.clone();
            return this;
        }

        /**
         * 设置数量图片列表
         * @param numberDrawableArray numberDrawableArray
         * @return Builder
         */
        public Builder setNumberDrawableArray(int[] numberDrawableArray) {
            this.numberDrawableArray = numberDrawableArray.clone();
            return this;
        }

        /**
         * 设置等级图片列表
         * @param levelDrawableArray levelDrawableArray
         * @return Builder
         */
        public Builder setLevelDrawableArray(int[] levelDrawableArray) {
            this.levelDrawableArray = levelDrawableArray.clone();
            return this;
        }

        /**
         * 设置等级文字列表
         * @param levelStringArray levelStringArray
         * @return Builder
         */
        public Builder setLevelStringArray(String[] levelStringArray) {
            this.levelStringArray = levelStringArray.clone();
            return this;
        }

        /**
         * 设置文字大小
         * @param textSize textSize
         * @return Builder
         */
        public Builder setTextSize(float textSize) {
            this.textSize = textSize;
            return this;
        }

        /**
         *  建造者方法
         * @return Provider
         */
        public Provider build() {

            if (cacheSize == 0) {
                cacheSize = 32;
            }

            if (drawableArray == null || drawableArray.length == 0) {

                this.drawableArray = new int[]{ResourceTable.Media_super_like_default_icon};
            }

            if (levelDrawableArray == null && levelStringArray == null) {
                levelStringArray = new String[]{"鼓励!", "加油!!", "太棒了!!!"};
            }

            if (textSize < 24) {
                try {
//                    Float.parseFloat(context.getString(ResourceTable.String_slike_default_text_size))
                    textSize = PixelUtil.fp2px(14);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            return new Default(context, cacheSize, drawableArray, numberDrawableArray,
                    levelDrawableArray, levelStringArray, textSize);
        }
    }

    /**
     *  抽象接口集合
     */
    public interface Provider {
        /**
         * 获取随机图片
         * @return PixelMap
         */
        PixelMap getRandomBitmap();

        /**
         * getNumberBitmap
         * @param number number
         * @return PixelMap
         */
        PixelMap getNumberBitmap(int number);

        /**
         * getLevelBitmap
         * @param level level
         * @return PixelMap
         */
        PixelMap getLevelBitmap(int level);
    }
}
